﻿Imports System.Collections.Generic

Namespace Pop.Api
    ''' <summary>
    ''' 符合POP习惯的纯字符串字典结构。(可重复)
    ''' </summary>
    Public Class PopDictionary
        Inherits List(Of KeyValuePair(Of String, String))
        Private Const DATE_TIME_FORMAT As String = "yyyy-MM-dd HH:mm:ss"

        Public Sub New()
        End Sub

        Public Sub New(ByVal collection As IEnumerable(Of KeyValuePair(Of String, String)))
            MyBase.New(collection)
        End Sub

        Public Sub New(ByVal dictionary As IDictionary(Of String, String))
            MyBase.New(dictionary.GetEnumerator)
        End Sub

        ''' <summary>
        ''' 添加一个新的键值对。空键或者空值的键值对将会被忽略。
        ''' </summary>
        ''' <param name="key">键名称</param>
        ''' <param name="value">键对应的值</param>
        Public Overloads Sub Add(ByVal key As String, ByVal value As Object)
            Dim strValue As String = ValueToString(value)
            Me.Add(key, strValue)
        End Sub

        ''' <summary>
        ''' 添加一个新的键值对集合。空键或者空值的键值对将会被忽略。
        ''' </summary>
        ''' <param name="collection">键值对集合</param>
        Public Shadows Sub AddRange(ByVal collection As IEnumerable(Of KeyValuePair(Of String, Object)))
            For Each field In collection
                Me.Add(field.Key, field.Value)
            Next
        End Sub

        ''' <summary>
        ''' 将键对应的值转化为String
        ''' </summary>
        ''' <param name="value">键对应的值，目前支持：string, int, long, double, bool, DateTime类型</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function ValueToString(ByVal value As Object) As String
            Dim strValue As String

            If value Is Nothing Then
                strValue = Nothing
            ElseIf TypeOf value Is String Then
                strValue = DirectCast(value, String)
            ElseIf TypeOf value Is Nullable(Of DateTime) Then
                Dim dateTime As Nullable(Of DateTime) = DirectCast(value, Nullable(Of DateTime))
                strValue = dateTime.Value.ToString(DATE_TIME_FORMAT)
            ElseIf TypeOf value Is Nullable(Of Integer) Then
                strValue = DirectCast(value, Nullable(Of Integer)).Value.ToString()
            ElseIf TypeOf value Is Nullable(Of Long) Then
                strValue = DirectCast(value, Nullable(Of Long)).Value.ToString()
            ElseIf TypeOf value Is Nullable(Of Double) Then
                strValue = DirectCast(value, Nullable(Of Double)).Value.ToString()
            ElseIf TypeOf value Is Nullable(Of Boolean) Then
                strValue = DirectCast(value, Nullable(Of Boolean)).Value.ToString().ToLower()
            Else
                strValue = value.ToString()
            End If

            Return strValue
        End Function

        Public Overloads Sub Add(ByVal key As String, ByVal value As String)
            If Not String.IsNullOrEmpty(key) AndAlso Not String.IsNullOrEmpty(value) Then
                MyBase.Add(New KeyValuePair(Of String, String)(key, value))
            End If
        End Sub

        ''' <summary>
        ''' 获取无重复Key的字典枚举器
        ''' </summary>
        Public Overloads Function GetDictionary() As IDictionary(Of String, String)
            Dim dictionary As New Dictionary(Of String, String)
            For Each field In Me
                Dim key As String = field.Key
                Dim value As String = field.Value
                If dictionary.ContainsKey(key) Then
                    dictionary.Item(key) &= value
                Else
                    dictionary.Add(field.Key, field.Value)
                End If
            Next
            Return dictionary
        End Function
    End Class

    ''' <summary>
    ''' 符合POP习惯的纯字符串字典结构。(无重复)
    ''' </summary>
    Public Class PopDictionary_without_repetition
        Inherits Dictionary(Of String, String)
        Private Const DATE_TIME_FORMAT As String = "yyyy-MM-dd HH:mm:ss"

        Public Sub New()
        End Sub

        Public Sub New(ByVal collection As IEnumerable(Of KeyValuePair(Of String, String)))
            On Error Resume Next
            For Each field In collection
                Me.Add(field.Key, field.Value)
            Next
        End Sub

        Public Sub New(ByVal dictionary As IDictionary(Of String, String))
            MyBase.New(dictionary)
        End Sub

        ''' <summary>
        ''' 添加一个新的键值对。空键或者空值的键值对将会被忽略。
        ''' </summary>
        ''' <param name="key">键名称</param>
        ''' <param name="value">键对应的值</param>
        Public Shadows Sub Add(ByVal key As String, ByVal value As Object)
            Dim strValue As String = ValueToString(value)
            Me.Add(key, strValue)
        End Sub

        ''' <summary>
        ''' 将键对应的值转化为String
        ''' </summary>
        ''' <param name="value">键对应的值，目前支持：string, int, long, double, bool, DateTime类型</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function ValueToString(ByVal value As Object) As String
            Dim strValue As String

            If value Is Nothing Then
                strValue = Nothing
            ElseIf TypeOf value Is String Then
                strValue = DirectCast(value, String)
            ElseIf TypeOf value Is Nullable(Of DateTime) Then
                Dim dateTime As Nullable(Of DateTime) = DirectCast(value, Nullable(Of DateTime))
                strValue = dateTime.Value.ToString(DATE_TIME_FORMAT)
            ElseIf TypeOf value Is Nullable(Of Long) Then
                strValue = DirectCast(value, Nullable(Of Long)).Value.ToString()
            ElseIf TypeOf value Is Nullable(Of Long) Then
                strValue = DirectCast(value, Nullable(Of Long)).Value.ToString()
            ElseIf TypeOf value Is Nullable(Of Double) Then
                strValue = DirectCast(value, Nullable(Of Double)).Value.ToString()
            ElseIf TypeOf value Is Nullable(Of Boolean) Then
                strValue = DirectCast(value, Nullable(Of Boolean)).Value.ToString().ToLower()
            Else
                strValue = value.ToString()
            End If

            Return strValue
        End Function

        Public Shadows Sub Add(ByVal key As String, ByVal value As String)
            If Not String.IsNullOrEmpty(key) AndAlso Not String.IsNullOrEmpty(value) Then
                MyBase.Add(key, value)
            End If
        End Sub

    End Class
End Namespace